﻿using System.Text;
using Devonline.Core;
using Devonline.Logging;
using Devonline.MessageQueue;
using Devonline.MessageQueue.Pulsar;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

var commandLine = new CommandLineArgumentParser(args);
var host = commandLine.GetValue<string>("-h") ?? commandLine.GetValue<string>("--host") ?? "pulsar://api.pigeoncn.com";

var builder = WebApplication.CreateBuilder(args);
builder.Host.AddLogging();

var services = builder.Services;
services.AddLogging();
services.AddMessageQueue(new PulsarEndpoint { Name = nameof(Devonline.MessageQueue.Pulsar), Host = host }, ServiceLifetime.Singleton);

var app = builder.Build();
await app.StartAsync();

var logger = app.Services.GetService<ILogger<Program>>()!;
var messageQueue = app.Services.GetService<IMessageQueueService>()!;

try
{
    var tenant = commandLine.GetValue<string>("-t") ?? commandLine.GetValue<string>("--tenant") ?? "public";
    var argNamespace = commandLine.GetValue<string>("-n") ?? commandLine.GetValue<string>("--namespace") ?? "default";
    var schema = commandLine.GetValue<string>("-sc") ?? commandLine.GetValue<string>("--schema") ?? "String";
    var publish = commandLine.GetValue<string>("-p") ?? commandLine.GetValue<string>("--publish") ?? "dev";
    var subscribe = commandLine.GetValue<string>("-s") ?? commandLine.GetValue<string>("--subscribe") ?? "test";
    var subscriptionName = commandLine.GetValue<string>("-sn") ?? commandLine.GetValue<string>("--subscriptionName") ?? "pulsar-" + KeyGenerator.GetStringKey();
    var subscriptionType = commandLine.GetValue<string>("-st") ?? commandLine.GetValue<string>("--subscriptionType") ?? "Shared";

    logger.LogWarning("消息队列客户端已经启动, 当前版本: {0}", "v8.0.12.0219");
    logger.LogInformation("输入 {schema}#{content}@{publish} 形式将发送指定内容类型的消息内容到指定主题", "内容类型", "消息内容", "发布主题");
    logger.LogInformation("输入以上三种形式的两种组合, 剩余一种将采用缺省值; 仅输入一种, 则为 {schema} 或 {content}, 未输入 {publish} 将视为默认发布主题", "内容类型", "消息内容", "发布主题");
    logger.LogInformation("参数 {0} 设定服务器地址, 当前值: {1}", "-h | --host", host);
    logger.LogInformation("参数 {0} 设定租户, 当前值: {1}", "-t | --tenant", tenant);
    logger.LogInformation("参数 {0} 设定命名空间, 当前值: {1}", "-n | --namespace", argNamespace);
    logger.LogInformation("参数 {0} 设定默认发布主题, 当前值: {1}", "-p | --publish", publish);
    logger.LogInformation("参数 {0} 设定默认订阅主题, 当前值: {1}", "-s | --subscribe", subscribe);
    logger.LogInformation("参数 {0} 设定默认内容类型, 当前值: {1}", "-sc | --schema", schema);
    logger.LogInformation("参数 {0} 设定默认订阅名称, 当前值: {1}", "-sn | --subscriptionName", subscriptionName);
    logger.LogInformation("参数 {0} 设定默认订阅类型, 当前值: {1}", "-st | --subscriptionType", subscriptionType);
    logger.LogInformation("输入 {0} 退出", "quit");
    logger.LogInformation("输入其余任意内容将视为消息内容发布到默认发布主题: {0}", publish);

    await messageQueue.StartAsync();
    var subscribeTopic = $"persistent://{tenant}/{argNamespace}/{subscribe}";
    if (schema == "String")
    {
        await messageQueue.SubscribeAsync(subscribeTopic, subscriptionName, async message =>
        {
            logger.LogInformation("已收到主题: {subscribe} 的消息: " + message, subscribe);
            await Task.CompletedTask;
        }, subscriptionType);
    }

    var input = Console.ReadLine()?.Trim();
    while (input != "quit")
    {
        if (!string.IsNullOrWhiteSpace(input))
        {
            var array = input.Split(new char[] { AppSettings.CHAR_SHARP, AppSettings.CHAR_AT }, StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries);
            string? content = null;

            //length 目前只支持 1,2,3
            if (array.Length == 1)
            {
                content = input;
            }
            else if (array.Length == 2)
            {
                if (input.Contains(AppSettings.CHAR_AT))
                {
                    //content@publish 形式
                    content = array[0];
                    publish = array[1];
                }
                else
                {
                    //type#content 形式
                    schema = array[0];
                    content = array[1];
                }
            }
            else if (array.Length >= 3)
            {
                //type#?content@?publish 形式
                schema = array[0];
                content = array[1];
                publish = array[2];
            }
            else
            {
                content = input;
            }

            var topic = $"persistent://{tenant}/{argNamespace}/{publish}";
            if (schema == "String")
            {
                await messageQueue.PublishAsync(topic, content);
            }
            else
            {
                await messageQueue.PublishAsync(topic, Encoding.UTF8.GetBytes(content));
            }

            logger.LogInformation("已向主题: {publish} 发布消息: " + content, publish);
        }

        input = Console.ReadLine()?.Trim();
    }

    await messageQueue.StopAsync();
}
catch (Exception ex)
{
    logger.LogError(ex, "客户端出错, {message}", ex.GetInnerException());
}

await app.StopAsync();
logger.LogInformation("客户端退出, 消息队列连接结束!");